class Player:
  # Social follower: In the real world, people survive, yet they are not all playing game-theory-optimal strategies.  They tend to
  # use general heuristics to determine their actions at any given point.  One of the most simple heuristics that is easy to see in
  # any sort of group interaction is "shun the outsider".  Anyone who falls too far outside of 'normal' behaviour is not included in
  # the group.  In this game, this correlates to not cooperating with them by hunting.
  #
  # Another general heuristic that works well is 'move towards the middle'.  Birds use it to flock, fish use it to school, people use it
  # to calibrate their behaviour.  By moving towards the middle, you can guarantee that at least your general strategy does not vary too
  # much from that of people who have found successful strategies.  In this game, it corresponds to keeping your reputation as close to
  # the average reputation as possible.
  #
  # The last general heuristic I apply here, is in matters of life and death, look out for yourself first.  As food approaches a critical
  # level, hoarding seems to be an appropriate behaviour, and one that is seen in the real world.  As such, in the game, once food drops
  # below a certain threshold, no hunting is done, to make it last as long as possible.
  #
  # Notes: If this strategy is played against multiple copies of itself, the winner is the one who most closely guesses the initial slack
  # rate of all the other copies, and uses that as it's initial slack rate.  Because of this, the strategy could be highly sensitive to initial
  # slack rates, and a starting rate needs to be carefully chosen.  .66 was chosen because it is high enough to hopefully inspire cooperation
  # from other players, but centered enough that it can easily be adjusted to actual game scenarios in the second round.
  
  def __init__(self):
    self.prev_avg_rep = 0
    
    
  def hunt_choices(self, round_number, current_food, current_reputation, m,  player_reputations):
      hunt_decisions = []
      numbered_rep_list = []
      total_reputation = 0
      total_players = len(player_reputations)
      exp_avg_rep = 0
      
      #Calculate avg rep and generate a bit easier list to manipulate
      for i in range(0,total_players):
        hunt_decisions.append('h')
        total_reputation += player_reputations[i]
        numbered_rep_list.append({'index':i,'rep':player_reputations[i]})
      
      #find the average repuation of all the competitors
      avg_rep = total_reputation / total_players
      
      #sort the competitors by their reputation
      numbered_rep_list.sort(key=lambda item: abs(item['rep']-avg_rep))  
      
      #Use linear estimation to guess what average will be for next round (added a damping factor to try to minimize huge jumps)
      if round_number > 2:
        exp_avg_rep = avg_rep + .5*(avg_rep - self.prev_avg_rep)
      
      #Store avg_rep for use next round
      self.prev_avg_rep = avg_rep
      
      #set target to make my current rep equal to the expected average rep of next round
      target_rep = (round_number * exp_avg_rep - (current_reputation * (round_number-1)))
      
      #Set initial target to slacking 1/3rd of the time
      if round_number == 1:
        target_rep = .66
      
      #Limit target_rep to feasible values  
      if target_rep > 1:
        target_rep = 1
      if target_rep < 0:
        target_rep = 0
        
      #Set the amount of people to slack against to make my reputation equal to current average rep
      slack_list_size = int((1.0-target_rep)*total_players)
        
      #print("Curr:", current_reputation, "Avg:", avg_rep, "EA:", exp_avg_rep, "Tar:", target_rep, "S:", slack_list_size, "N:", total_players, "A:", 1-(slack_list_size/total_players))
      
      #Only slack against the outliers, keeping my current reputation as close as possible to the average rep
      for i in range(0,slack_list_size):  
        hunt_decisions[numbered_rep_list[-(i+1)]['index']]='s'
      
      #If I am running low on food, slack off in all rounds. (Trying this to pull of a late game win against strong opponents)
      if (current_food < (2.5 * len(player_reputations))):
        for i in range(0,len(hunt_decisions)):
          hunt_decisions[i]='s'
      
      return hunt_decisions;
  
  def hunt_outcomes(self, food_earnings):
      pass 
  
  def round_end(self, award, m, number_hunters):
      pass
